package plar.core;

import java.util.ArrayList;
import java.util.HashMap;

import org.jbox2d.collision.AABB;
import org.jbox2d.common.Vec2;

import plar.core.Action;
import plar.core.Common;
import plar.core.Element;
import plar.core.Level;
import plar.core.Parameters;
import plar.core.Gun;
import plar.core.Player;

public class Input implements Action{

	ArrayList<String> currentKeys;
	HashMap<String, Float> directions;
	Parameters info;
	int moving = 0;
	int movingtotal = 3;
	
	public ArrayList<String> popKeys() {
		if (keysQueue.size() == 0)
			return null;
		ArrayList<String> keys = new ArrayList<String>(keysQueue.get(0));
		keysQueue.remove(0);
		return keys;
	}
	
	public ArrayList<ArrayList<String>> keysQueue;
	
	public Input(Element me) {

		directions = new HashMap<String, Float>();
		currentKeys = new ArrayList<String>();
		info = new Parameters();
		info.put("me", me);
		info.put("subAction", "new");
		keysQueue = new ArrayList<ArrayList<String>>();
	}
	
	public Parameters call(Parameters parameters) {

		Player me = (Player) parameters.get("me");
		Level l = (Level) parameters.get("level");
		String subAction = (String) parameters.get("subAction");

		if (subAction == "main") {
			//Common.info("main rutine");
			me.setProperty("isFiring", false);
			boolean isDown=false;
			if(me.getProperty("isDown")!=null) isDown = (Boolean)me.getProperty("isDown");
			boolean onAir=true;
			AABB r = me.getAABB();
			r.lowerBound.y+=0.1f;
			r.lowerBound.x+=0.1f;
			r.upperBound.x-=0.1f;
			r.upperBound.y+=0.05f;
			try
			{
				if (me.level.world.inRange(r) && me.level.world.query(r, 500).length>1) onAir=false;
				//Common.info(5,"Input.call() query.length:"+me.level.world.query(r, 2).length);
			
				}catch(Exception ex)
	{
		Common.info(1,"Level.getScreen() got exception:"+ex);
	}
			//catch(Exception ex)
			//{
			//	Common.info(1,"iException! Input.call() onAir=?"+ex);
			//}
			//Common.info(7,"Input.step(), floor:"+me.level.world.query(r, 2).length);
			ArrayList<String> newKeys = new ArrayList<String>();
			newKeys = popKeys();
			//if(newKeys==null)		newKeys = currentKeys;
			if(newKeys==null)	return null;
			boolean reduced = false;
		//	Common.info("input handler: " + newKeys.toString());
			Parameters p = new Parameters(info);
			float runSpeed = (Float)me.getProperty("runSpeed");
			if(onAir)  runSpeed = (Float)me.getProperty("airySpeed");
			if (newKeys.contains("right"))
				me.setProperty("direction", 0.0);
			if (newKeys.contains("left"))
				me.setProperty("direction", 1.0);
				
				if(onAir)
				{
			if (newKeys.contains("right")) {
				me.applySpeed(new Vec2(runSpeed,0));
			//	me.applyForce(new Vec2(runSpeed*6,0));
			}
			if (newKeys.contains("left")) {
				
				//me.applyForce(new Vec2(-runSpeed*6,0));
				me.applySpeed(new Vec2(-runSpeed,0));
			}			
					
				}
			if(!onAir)
			{	
				if (newKeys.contains("down")) {
					reduced=true;
				}
			if (newKeys.contains("right")) {
				me.setSpeed(new Vec2(runSpeed,0));
				//me.applyForce(new Vec2(runSpeed*1226,0));
			}
			if (newKeys.contains("left")) {
				
				//me.applyForce(new Vec2(-runSpeed*1226,0));
				me.setSpeed(new Vec2(-runSpeed,0));
			}			
			
			

			if (newKeys.contains("jump") && !currentKeys.contains("jump")) {
				
			
					
				me.applySpeed(new Vec2(0,-(Float)me.getProperty("jumpSpeed")));
			}
			}
						if (newKeys.contains("1") && !currentKeys.contains("1")) {
							Common.info(7,"gun!");
					me.setCurrentGun(0);
				}
								if (newKeys.contains("2") && !currentKeys.contains("2")) {
							Common.info(7,"gun!");
					me.setCurrentGun(1);
				}
								if (newKeys.contains("3") && !currentKeys.contains("3")) {
							Common.info(7,"gun!");
					me.setCurrentGun(2);
				}
			
			if (newKeys.contains("fire") && !currentKeys.contains("fire")) {
				int cg = me.getCurrentGun();
				Gun g = me.gl.get(cg);
				Common.info(3,"--------> is firing "+me+ " with"+cg+":"+g);
				g.fire();
				me.setProperty("isFiring", true);
			}
			
			
			if(isDown!=reduced)
			{
				Common.info(5,"reducing varied"+reduced);
				me.level.world.destroyBody(me.body);
				Vec2 oldSpeed = new Vec2(me.getSpeed().x,me.getSpeed().y);
				Vec2 oldPos = new Vec2(me.getPosition().x,me.getPosition().y);
				Vec2 oldSize = new Vec2(me.getSize().x,me.getSize().y);
				me.initBox();
				

				if(!reduced)
				{
					Vec2 newSize = (Vec2)me.getProperty("standardSize");
					me.setPosition(oldPos.x,oldPos.y+oldSize.y/2f-newSize.y/2);
					me.setSize(newSize.x,newSize.y);
					me.setProperty("isDown", false);
				}
				if(reduced)
				{
					Vec2 newSize = (Vec2)me.getProperty("reducedSize");
					me.setPosition(oldPos.x,oldPos.y+oldSize.y/2f-newSize.y/2);
					me.setSize(newSize.x,newSize.y);
					me.setProperty("isDown", true);
				}
				me.level.AddElement(me);
				me.applySpeed(oldSpeed);
			}
			
			currentKeys = newKeys;
		} else if (subAction == "input") {
			ArrayList<String> inputkeys = (ArrayList<String>) parameters
					.get("key");

			keysQueue.add(inputkeys);
			Common.info(3,"input : " + inputkeys.toString());
		}

		return null;
	}

}
